---
title: ImagePicker
description: A library that provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera.
sourceCodeUrl: 'https://github.com/expo/expo/tree/sdk-52/packages/expo-image-picker'
packageName: 'expo-image-picker'
iconUrl: '/static/images/packages/expo-image-picker.png'
platforms: ['android', 'ios', 'web']
---

import { GithubIcon } from '@expo/styleguide-icons/custom/GithubIcon';

import APISection from '~/components/plugins/APISection';
import { APIInstallSection } from '~/components/plugins/InstallSection';
import { AndroidPermissions, IOSPermissions } from '~/components/plugins/permissions';
import { BoxLink } from '~/ui/components/BoxLink';
import {
  ConfigReactNative,
  ConfigPluginExample,
  ConfigPluginProperties,
} from '~/ui/components/ConfigSection';
import { ContentSpotlight } from '~/ui/components/ContentSpotlight';
import { SnackInline } from '~/ui/components/Snippet';
import { PlatformTags } from '~/ui/components/Tag/PlatformTags';

`expo-image-picker` provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera.

<ContentSpotlight file="sdk/imagepicker.mp4" loop={false} />

## Installation

<APIInstallSection />

#### Known issues&ensp;<PlatformTags platforms={['ios']} />

On iOS, when an image (usually of a [higher resolution](http://www.openradar.me/49866214)) is picked from the camera roll, the result of the cropped image gives the wrong value for the cropped rectangle in some cases. Unfortunately, this issue is with the underlying `UIImagePickerController` due to a bug in the closed-source tools built into iOS.

## Configuration in app config

You can configure `expo-image-picker` using its built-in [config plugin](/config-plugins/introduction/) if you use config plugins in your project ([Continuous Native Generation (CNG)](/workflow/continuous-native-generation/)). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does **not** use CNG, then you'll need to manually configure the library.

<ConfigPluginExample>

```json app.json
{
  "expo": {
    "plugins": [
      [
        "expo-image-picker",
        {
          "photosPermission": "The app accesses your photos to let you share them with your friends."
        }
      ]
    ]
  }
}
```

</ConfigPluginExample>

<ConfigPluginProperties
  properties={[
    {
      name: 'photosPermission',
      platform: 'ios',
      description: 'A string to set the `NSPhotoLibraryUsageDescription` permission message.',
      default: '"Allow $(PRODUCT_NAME) to access your photos"',
    },
    {
      name: 'cameraPermission',
      platform: 'ios',
      description: 'A string to set the `NSCameraUsageDescription` permission message.',
      default: '"Allow $(PRODUCT_NAME) to access your camera"',
    },
    {
      name: 'microphonePermission',
      platform: 'ios',
      description: 'A string to set the `NSMicrophoneUsageDescription` permission message.',
      default: '"Allow $(PRODUCT_NAME) to access your microphone"',
    },
  ]}
/>

<ConfigReactNative>

If you're not using Continuous Native Generation ([CNG](/workflow/continuous-native-generation/)) or you're using a native **ios** project manually, then you need to add `NSPhotoLibraryUsageDescription`, `NSCameraUsageDescription`, and `NSMicrophoneUsageDescription` keys to your **ios/[app]/Info.plist**:

```xml Info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>Give $(PRODUCT_NAME) permission to save photos</string>
<key>NSCameraUsageDescription</key>
<string>Give $(PRODUCT_NAME) permission to access your camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>Give $(PRODUCT_NAME) permission to use your microphone</string>
```

</ConfigReactNative>

## Usage

<SnackInline label='Image Picker' dependencies={['expo-image-picker']}>

```tsx
import { useState } from 'react';
import { Button, Image, View, StyleSheet } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function ImagePickerExample() {
  const [image, setImage] = useState<string | null>(null);

  const pickImage = async () => {
    // No permissions request is necessary for launching the image library
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ['images', 'videos'],
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    console.log(result);

    if (!result.canceled) {
      setImage(result.assets[0].uri);
    }
  };

  return (
    <View style={styles.container}>
      <Button title="Pick an image from camera roll" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={styles.image} />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: 200,
    height: 200,
  },
});
```

</SnackInline>

When you run this example and pick an image, you will see the image that you picked show up in your app, and a similar log will be shown in the console:

```json collapseHeight=425
{
  "assets": [
    {
      "assetId": "C166F9F5-B5FE-4501-9531",
      "base64": null,
      "duration": null,
      "exif": null,
      "fileName": "IMG.HEIC",
      "fileSize": 6018901,
      "height": 3025,
      "type": "image",
      "uri": "file:///data/user/0/host.exp.exponent/cache/cropped1814158652.jpg"
      "width": 3024
    }
  ],
  "canceled": false
}
```

### With AWS S3

<BoxLink
  title="AWS storage example"
  description="An example of how to use AWS storage can be found in with-aws-storage-upload."
  Icon={GithubIcon}
  href="https://github.com/expo/examples/tree/master/with-aws-storage-upload"
/>

See [Amplify documentation](https://docs.amplify.aws/) guide to set up your project correctly.

### With Firebase

<BoxLink
  title="Firebase storage example"
  description="An example of how to use Firebase storage can be found in with-firebase-storage-upload."
  Icon={GithubIcon}
  href="https://github.com/expo/examples/tree/master/with-firebase-storage-upload"
/>

See [Using Firebase](/guides/using-firebase/) guide to set up your project correctly.

## API

```js
import * as ImagePicker from 'expo-image-picker';
```

<APISection packageName="expo-image-picker" apiName="ImagePicker" />

## Permissions

### Android

The following permissions are added automatically through the library's **AndroidManifest.xml**.

<AndroidPermissions permissions={['CAMERA', 'READ_EXTERNAL_STORAGE', 'WRITE_EXTERNAL_STORAGE']} />

### iOS

The following usage description keys are used by the APIs in this library.

<IOSPermissions
  permissions={[
    'NSMicrophoneUsageDescription',
    'NSPhotoLibraryUsageDescription',
    'NSCameraUsageDescription',
  ]}
/>
